package com.css.fxfzypg.logInfo;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.logInfo.entity.SLog;
import com.css.fxfzypg.logInfo.service.SysLogService;
import com.css.fxfzypg.util.CreateGson;
import com.css.fxfzypg.web.PlatformSessionContext;
import com.css.fxfzypg.zcpt.sys.entity.SUser;
import com.css.fxfzypg.zcpt.sys.service.SUserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slw.common.helper.PropsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Slf4j
@Aspect
@Component
public class AopLog {
    @Autowired
    SUserService sUserService;
    @Resource
    private SysLogService sysLogService;

    private static final String sysId = PropsHelper.loadProps("slw-config.properties").getProperty("app.system.id");

    // 声明切点com.css.fxfzypg.logInfo.SysLog
    @Pointcut("@annotation(com.css.fxfzypg.logInfo.SysLog)")
    public void logPointCut() {
    }

    /**
     * 环绕通知 @Around  ， 当然也可以使用 @Before (前置通知)  @After (后置通知)
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //多次执行会调用被代理方法多次
        Object result = point.proceed();
        MethodSignature signature = (MethodSignature) point.getSignature();
        try {
            saveLog(signature,result);
        } catch (Exception e) {
            log.info("aop日志错误,原因为:"+e.toString());
        }
        return result;
    }

    /**
     * 保存日志
     *
     * @param signature
     * @param o
     */
    private void saveLog(MethodSignature signature,Object o) throws Throwable {
        JSONObject resultJson = (JSONObject) JSON.toJSON(o);
        String code = resultJson.getObject("code", String.class);
        Method method = signature.getMethod();
        SLog sysLogBO = new SLog();
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if (sysLog != null) {
            //注解上的描述(功能代码)
            sysLogBO.setLogMemo(sysLog.value());
        }
        String user = sUserService.getSUser(PlatformSessionContext.getUserID());
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        //操作人
        sysLogBO.setOpName(sUser.getUserName());
        //操作ip
        sysLogBO.setOpIp(getIP());
        //事件类型(统一写普通业务事件)
        sysLogBO.setEventType(0);
        //操作结果
        sysLogBO.setOpResult(code.equals("200") ? "success" : "error");
        //系统代码
        sysLogBO.setSysId(sysId);
        log.info("写入日志");
        //写入日志
        sysLogService.saveLogs(sysLogBO);
    }


    /**
     * 获取id
     *
     * @return
     */
    private static String getIP() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = request.getHeader("x-forwarded-for");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

            ip = request.getHeader("Proxy-Client-IP");

        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

            ip = request.getHeader("WL-Proxy-Client-IP");

        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

            ip = request.getRemoteAddr();

        }

        return ip;
    }


}
